package com.vodafone.nowplus.android.peoplemail.activity;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.XmlResourceParser;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.AdapterView;
import android.widget.ListView;

import com.vodafone.nowplus.android.peoplemail.Account;
import com.vodafone.nowplus.android.peoplemail.K9;
import com.vodafone.nowplus.android.peoplemail.Preferences;
import com.vodafone.nowplus.android.peoplemail.R;
import com.vodafone.nowplus.android.peoplemail.activity.setup.AccountSetupCheckSettings;
import com.vodafone.nowplus.android.peoplemail.singlesignon.CertificateReader;
import com.vodafone.nowplus.android.peoplemail.singlesignon.SSOSender;
import com.vodafone.nowplus.android.peoplemail.singlesignon.UserData;




public class K9ListActivity extends ListActivity {
    
    private SSOSender ssoSender;
    private Activity ssoCaller;
    private Account mAccount;

    @Override
    public void onCreate(Bundle icicle)
    {
        //Log.i(K9.LOG_TAG, "K9ListActivity.onCreate");
        K9Activity.setLanguage(this, K9.getK9Language());
        if(K9.USE_360_SSO) {
        	ssoSender=new SSOSender(this);
        }
        
        super.onCreate(icicle);
        setupFormats();
    }

    @Override
    public void onResume()
    {
        super.onResume();
        setupFormats();
    }

    private java.text.DateFormat mDateFormat;
    private java.text.DateFormat mTimeFormat;

    private void setupFormats()
    {
        mDateFormat = DateFormatter.getDateFormat(this);
        mTimeFormat = android.text.format.DateFormat.getTimeFormat(this);   // 12/24 date format
    }

    public java.text.DateFormat getTimeFormat()
    {
        return mTimeFormat;
    }

    public java.text.DateFormat getDateFormat()
    {
        return mDateFormat;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        // Shortcuts that work no matter what is selected
        switch (keyCode)
        {
            case KeyEvent.KEYCODE_VOLUME_UP:
            {
                final ListView listView = getListView();
                if (K9.useVolumeKeysForListNavigationEnabled())
                {
                    int currentPosition = listView.getSelectedItemPosition();
                    if (currentPosition == AdapterView.INVALID_POSITION || listView.isInTouchMode())
                    {
                        currentPosition = listView.getFirstVisiblePosition();
                    }
                    if (currentPosition > 0)
                    {
                        listView.setSelection(currentPosition - 1);
                    }
                    return true;
                }
            }
            case KeyEvent.KEYCODE_VOLUME_DOWN:
            {
                final ListView listView = getListView();
                if (K9.useVolumeKeysForListNavigationEnabled())
                {
                    int currentPosition = listView.getSelectedItemPosition();
                    if (currentPosition == AdapterView.INVALID_POSITION || listView.isInTouchMode())
                    {
                        currentPosition = listView.getFirstVisiblePosition();
                    }
                    
                    if (currentPosition < listView.getCount())
                    {
                        listView.setSelection(currentPosition + 1);
                    }
                    return true;
                }
            }
        }
        return super.onKeyDown(keyCode, event);
    }
 
    
	public void onSSOResult(int resultCode, Intent data) {
		// There was an answer, so there must be an 360 app installed
		boolean loggedIn = false;
		if (resultCode != RESULT_OK) {
			return;
		}

		UserData userData = new UserData();
		try {
			userData.readFromIntent(data);
			userData.deCryptUserData(CertificateReader.getInstance(this).getPrivateKey());
			if (userData.loggedIn.equals("true")) {
				loggedIn = true;
				ssoSender.interrupt();
			}
		} catch (Exception e) {
			// we don't want to crash here, so we catch everything.
			Log.e(K9.LOG_TAG, "could not read SSO result", e);
		}

		if (loggedIn) {
			finishAutoSetup(userData);
		} else {
			gotoStartPeopleApp();
		}
	}
	
    public void onSetupCheckResult(int resultCode,Intent data){
        if (resultCode == RESULT_OK) {
            mAccount.setDescription(mAccount.getEmail());
            mAccount.save(Preferences.getPreferences(this));
            Preferences.getPreferences(this).setDefaultAccount(mAccount);
            K9.setServicesEnabled(this);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        
        if (requestCode== SSOSender.LOGIN_DETAILS_REQUEST_CODE){
            onSSOResult(resultCode,data);
        }    
        
        if (requestCode==AccountSetupCheckSettings.ACTIVITY_REQUEST_CODE){
            onSetupCheckResult(resultCode, data);
        }
        
       
       
        super.onActivityResult(requestCode, resultCode, data);
        
    }
    
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event)
    {
        // Swallow these events too to avoid the audible notification of a volume change
        if (K9.useVolumeKeysForListNavigationEnabled())
        {
            if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))
            {
                if (K9.DEBUG)
                    Log.v(K9.LOG_TAG, "Swallowed key up.");
                return true;
            }
        }
        return super.onKeyUp(keyCode,event);
    }

    /**
     * handle startup. Look for 360 people app.
     * @return true if handled (calling function shall do nothing)
     */
    protected void handle360Startup() {

		// do SSO startup 
		if (K9.USE_360_SSO && !ssoSender.sendGetUserDataRequest()) {
			showMessageAndGotoPeopleAppFromMarket();
		}

    }


    private void showWelcomeMessageForUsername(String username) {
        // show the dialog
        // show message
        final Dialog d = new AlertDialog.Builder(this).setTitle(
                R.string.account_welcome_dlg_title).setMessage(
                getString(R.string.account_welcome_dlg_txt)).setPositiveButton(
                R.string.okay_action, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                }).create();
        
        d.show();
        
        // save info that we showed it to this user
        SharedPreferences settings = getSharedPreferences(K9.PEOPLE_MAIL_SETTINGS_NAME, 0);
        String usernames = settings.getString(K9.PEOPLE_MAIL_SETTINGS_KEY_WELCOME_MESSAGE, "");
        usernames += ",'"+username+"'";
        SharedPreferences.Editor editor = settings.edit();
        editor.putString(K9.PEOPLE_MAIL_SETTINGS_KEY_WELCOME_MESSAGE, usernames);
        editor.commit();
        
    }

    /**
     * @param username
     * @return true if 'username' is in the list of usernames to which we showed the welcome message dialog
     */
    private boolean welcomeMessageShownForUsername(String username) {
        SharedPreferences settings = getSharedPreferences(K9.PEOPLE_MAIL_SETTINGS_NAME, 0);
        String usernames = settings.getString(K9.PEOPLE_MAIL_SETTINGS_KEY_WELCOME_MESSAGE, "");
        
        return usernames.contains("'"+username+"'");
    }

    /**
     * 
     */
    private void gotoStartPeopleApp() {
        try {
            // start people app
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            //start.setPackage("com.vodafone360.people");
            intent.addFlags(0x10200000);
            intent.setComponent(new ComponentName(K9.PEOPLE_PACKAGE_NAME, K9.START_LOGIN_ACTIVITY));
            startActivity(intent);
        } catch(Exception e) {
            Log.e(K9.LOG_TAG, "Exception", e);
        }
        // finish 360 Mail
       // finish();
        
    }

    /**
     * 
     */
    private void showMessageAndGotoPeopleAppFromMarket() {
        Log.i(K9.LOG_TAG, "starting market, pointing to people app...");
        // show message
        final Dialog d = new AlertDialog.Builder(this).setTitle(
                R.string.account_get_people_app_dlg_title).setMessage(
                getString(R.string.account_get_people_app_dlg_instructions)).setPositiveButton(
                R.string.okay_action, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                        // go to market
                        try {
                            Uri uri = Uri.parse(K9.MARKET_URL_PEOPLE_APP);
                            Intent it = new Intent(Intent.ACTION_VIEW, uri);
                            startActivity(it);
                        } catch (Exception e) {
                            Log.e("K9ListActivity","showMessageAndGotoPeopleAppFromMarket",e);
                        }
                        finish();
                    }
                }).setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
                finish();
            }
        }).create();
        
        d.show();

    }
    private Provider findProviderForDomain(String domain) {
        try {
            XmlResourceParser xml = getResources().getXml(R.xml.providers);
            int xmlEventType;
            Provider provider = null;
            while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
                if (xmlEventType == XmlResourceParser.START_TAG && "provider".equals(xml.getName())
                        && domain.equalsIgnoreCase(getXmlAttribute(xml, "domain"))) {
                    provider = new Provider();
                    provider.id = getXmlAttribute(xml, "id");
                    provider.label = getXmlAttribute(xml, "label");
                    provider.domain = getXmlAttribute(xml, "domain");
                    provider.note = getXmlAttribute(xml, "note");
                } else if (xmlEventType == XmlResourceParser.START_TAG && "incoming".equals(xml.getName())
                        && provider != null) {
                    provider.incomingUriTemplate = new URI(getXmlAttribute(xml, "uri"));
                    provider.incomingUsernameTemplate = getXmlAttribute(xml, "username");
                } else if (xmlEventType == XmlResourceParser.START_TAG && "outgoing".equals(xml.getName())
                        && provider != null) {
                    provider.outgoingUriTemplate = new URI(getXmlAttribute(xml, "uri"));
                    provider.outgoingUsernameTemplate = getXmlAttribute(xml, "username");
                } else if (xmlEventType == XmlResourceParser.END_TAG && "provider".equals(xml.getName())
                        && provider != null) {
                    return provider;
                }
            }
        } catch (Exception e) {
            Log.e(this.getClass().getName(), "Error while trying to load provider settings.", e);
        }
        return null;
    }

    private void finishAutoSetup(UserData userData) {
        String account = userData.userName;
        String password = userData.password;

        String user = userData.userName;
        String domain = "360.com";
        URI incomingUri = null;
        URI outgoingUri = null;
        try {
            String userEnc = URLEncoder.encode(user, "UTF-8");
            String passwordEnc = URLEncoder.encode(password, "UTF-8");
            Provider mProvider =findProviderForDomain(domain);
            String incomingUsername = mProvider.incomingUsernameTemplate;
            incomingUsername = incomingUsername.replaceAll("\\$email", account);
            incomingUsername = incomingUsername.replaceAll("\\$user", userEnc);
            incomingUsername = incomingUsername.replaceAll("\\$domain", domain);

            URI incomingUriTemplate = mProvider.incomingUriTemplate;
            incomingUri = new URI(incomingUriTemplate.getScheme(), incomingUsername + ":" + passwordEnc,
                    incomingUriTemplate.getHost(), incomingUriTemplate.getPort(), null, null, null);

            String outgoingUsername = mProvider.outgoingUsernameTemplate;
            outgoingUsername = outgoingUsername.replaceAll("\\$email", account);
            outgoingUsername = outgoingUsername.replaceAll("\\$user", userEnc);
            outgoingUsername = outgoingUsername.replaceAll("\\$domain", domain);

            URI outgoingUriTemplate = mProvider.outgoingUriTemplate;
            outgoingUri = new URI(outgoingUriTemplate.getScheme(), outgoingUsername + ":" + passwordEnc,
                    outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null, null, null);

            mAccount = Preferences.getPreferences(this).newAccount();
            mAccount.setName(userData.firstName);
            mAccount.setEmail(account);
            mAccount.setStoreUri(incomingUri.toString());
            mAccount.setTransportUri(outgoingUri.toString());
            mAccount.setDraftsFolderName(getString(R.string.special_mailbox_name_drafts));
            mAccount.setTrashFolderName(getString(R.string.special_mailbox_name_trash));
            mAccount.setArchiveFolderName(getString(R.string.special_mailbox_name_archive));
            mAccount.setSpamFolderName(getString(R.string.special_mailbox_name_spam));
            mAccount.setOutboxFolderName(getString(R.string.special_mailbox_name_outbox));
            mAccount.setSentFolderName(getString(R.string.special_mailbox_name_sent));
            AccountSetupCheckSettings.actionCheckSettings(this, mAccount, true, true);
          
            if (ssoCaller!=null){
                //ssoCaller.finish();
            }
        } catch (UnsupportedEncodingException enc) {
            // This really shouldn't happen since the encoding is hardcoded to
            // UTF-8
            Log.e(this.getClass().getName(), "Couldn't urlencode username or password.", enc);
        } catch (URISyntaxException use) {
         
        }
    }

    static class Provider implements Serializable {
        private static final long serialVersionUID = 8511656164616538989L;

        public String id;

        public String label;

        public String domain;

        public URI incomingUriTemplate;

        public String incomingUsernameTemplate;

        public URI outgoingUriTemplate;

        public String outgoingUsernameTemplate;

        public String note;
    }
    /**
     * Attempts to get the given attribute as a String resource first, and if it
     * fails returns the attribute as a simple String value.
     * 
     * @param xml
     * @param name
     * @return
     */
    private String getXmlAttribute(XmlResourceParser xml, String name) {
        int resId = xml.getAttributeResourceValue(null, name, 0);
        if (resId == 0) {
            return xml.getAttributeValue(null, name);
        } else {
            return getString(resId);
        }
    }
}
